package com.huadao.cart_ccs.experiment.test;

import com.huadao.cart_ccs.data.bo.BaseBO;
import com.huadao.cart_ccs.data.bo.CommandWord;
import com.huadao.cart_ccs.data.bo.ElectronicScaleBO;
import com.huadao.cart_ccs.modle.CO2Modle;
import com.huadao.cart_ccs.modle.ElectronicScaleModle;
import com.huadao.cart_ccs.modle.LiquidLevelModel;
import com.huadao.cart_ccs.modle.O2Modle;
import com.huadao.cart_ccs.modle.PeristalticPumpModle;
import com.huadao.cart_ccs.modle.PumpControlModle;
import com.huadao.cart_ccs.modle.TemperatureModle;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 暴力测试
 */
public class ForceTestPresenter extends ForceTestContract.IForceTestPresenter {
    private ElectronicScaleModle electronicScaleModle;
    private PeristalticPumpModle peristalticPumpModle;
    private PumpControlModle controlModle;
    private CO2Modle co2Modle;
    private O2Modle o2Modle;
    private TemperatureModle temperatureModle;
    private LiquidLevelModel liquidLevelModel;
    private ForceTestContract.IForceTestView baseView;
    private List<BaseBO> resultList;
    private int exceptionDataCount = 0;
    private double error;
    private double target;
    private int times;
    //记录更新数据
    private int updateIndex;
    //统计结果
    private Map<Double,Integer> staticsResult;
    private boolean isFinish;
    private boolean interrupt;

    public ForceTestPresenter(ForceTestContract.IForceTestView baseView) {
        this.baseView = baseView;
        electronicScaleModle = new ElectronicScaleModle();
        peristalticPumpModle = new PeristalticPumpModle();
        controlModle = new PumpControlModle();
        co2Modle = new CO2Modle();
        o2Modle = new O2Modle();
        temperatureModle = new TemperatureModle();
        liquidLevelModel = new LiquidLevelModel();
        EventBus.getDefault().register(this);
        resultList = new ArrayList<>();
        staticsResult = new HashMap<>();
    }

    @Override
    void operate() {
        initAnysisData();
        new Thread(new Runnable() {
            @Override
            public void run() {
                int operate = baseView.getOperate();
                int times = baseView.getTimes();
                while (times > 0 && !interrupt) {
                    switch (operate) {
                        case 0:
                            electronicScaleModle.weight();
                            break;
                        case 1:
                            electronicScaleModle.peel(new byte[]{0, 0, 0, 0});
                            break;
                        case 2:
                            controlModle.readFeedLiquorPump();
                            break;
                        case 3:
                            controlModle.readWasteLiquorPump();
                            break;
                        case 4:
                            controlModle.readCirculatingPump();
                            break;
                        case 5:
                            controlModle.readRecyclingPump();
                            break;
                        case 6:
                            co2Modle.readCO2();
                            break;
                        case 7:
                            o2Modle.readO2();
                            break;
                        case 8:
                            temperatureModle.readTemperature();
                            break;
                        case 9:
                            liquidLevelModel.readLiquidLevel();
                            break;
                        default:
                            break;
                    }
                    times--;
                    //                    try {
                    //                        Thread.sleep(SerialPortSource.minSendTimeGap);
                    //                    } catch (InterruptedException e) {
                    //                        e.printStackTrace();
                    //                    }
                }
            }
        }).start();
    }

    private void initAnysisData() {
        times = baseView.getTimes();
        target = baseView.getTargetDate();
        error = baseView.getError();
        interrupt = false;
    }

    @Override
    public void stop() {
        interrupt = true;

    }

    @Override
    List<BaseBO> getResultList() {
        return resultList;
    }

    @Override
    public void detachView() {
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }
        super.detachView();
    }

    @Override
    public void clear() {
        resultList.clear();
        baseView.notifyList();
        exceptionDataCount = 0;
        error = 0;
        target = 0;
        times = 0;
        updateIndex = 0;
        isFinish = false;
        staticsResult.clear();
        baseView.showExceptionDataCount(exceptionDataCount);
    }

    //    @Subscribe(threadMode = ThreadMode.MAIN)
    private void onMessageWeightEvent(ElectronicScaleBO event) {
        synchronized (this) {
            int index = resultList.size();
            resultList.add(event);
            baseView.onAddResult(index);
            if (isException(event)) {
                exceptionDataCount++;
                baseView.showExceptionDataCount(exceptionDataCount);
            }
            if (resultList.size() == times) {
                baseView.onFinish();
                isFinish = true;
            }

            Double key;
            if (event.getCommondWord() == CommandWord.readFail[0] || event.getCommondWord() == CommandWord.writeFail[0]) {
                key = -1d;
            } else {
                key = event.getWeight();
            }
            if (staticsResult.containsKey(key)) {
                staticsResult.put(key, staticsResult.get(key) + 1);
            } else {
                staticsResult.put(key, 1);
            }
        }
    }

    private boolean isException(ElectronicScaleBO event) {
        if (event.getCommondWord() == CommandWord.readFail[0] || event.getCommondWord() == CommandWord.writeFail[0]) {
            return true;
        }
        double data = event.getWeight();
        if (data > target + error || data < target - error) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public Map<Double,Integer> getStaticsResult() {
        return staticsResult;
    }

    @Override
    public boolean isFinish() {
        return isFinish;
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(BaseBO event) {
        synchronized (this) {
            if (event instanceof ElectronicScaleBO) {
                onMessageWeightEvent((ElectronicScaleBO) event);
            } else {
                int index = resultList.size();
                resultList.add(event);
                baseView.onAddResult(index);
                if (event.getCommondWord() == CommandWord.readFail[0] || event
                        .getCommondWord() == CommandWord.writeFail[0]) {
                    exceptionDataCount++;
                    baseView.showExceptionDataCount(exceptionDataCount);
                }
                if (resultList.size() == times) {
                    baseView.onFinish();
                    isFinish = true;
                }

                Double key;
                if (event.getCommondWord() == CommandWord.readFail[0] || event
                        .getCommondWord() == CommandWord.writeFail[0]) {
                    key = -1d;
                } else {
                    key = 1d;
                }
                if (staticsResult.containsKey(key)) {
                    staticsResult.put(key, staticsResult.get(key) + 1);
                } else {
                    staticsResult.put(key, 1);
                }
            }
        }
    }
}
